package com.bidevalution.business.job;

import com.bidevalution.business.factory.StepJobJdbcFactory;
import com.bidevalution.business.service.JdbcTemplateService;
import com.bidevalution.dao.entity.*;
import com.bidevalution.support.context.Constants;
import com.google.common.collect.Maps;
import com.qtp.core.util.DateUtil;
import com.qtp.core.util.IdsUtil;
import com.qtp.core.util.OConvertUtils;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description: 商务标评审-计算错误检查计算
 * @author: xiayf
 * @date: 2019-10-14 15:07
 */
public class ComputerErrorCheckNewJob implements StepJobJdbcFactory {

    private JdbcTemplateService jdbcTemplateService;
    private Logger log = LogManager.getLogger(getClass());
    //常量
    private static final Double MONEY = 5000000d;
    private static final String JYPB_CODE = "10101";


    @Override
    public void setJdbcTemplateService(JdbcTemplateService jdbcTemplateService) {
        this.jdbcTemplateService = jdbcTemplateService;
    }

    @Override
    public Boolean execute(BeSectionStepJob beSectionStepJob, String submitCode, String expertId, String layouCode) throws Exception {
        try {
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("sectionStepId", beSectionStepJob.getSectionStepId());
            paramMap.put("submitCode", submitCode);
            paramMap.put("sectionId", beSectionStepJob.getSectionId());
            double param = 0.005;
            StringBuilder sb = new StringBuilder();
            //查询方法代码，简易评标法按0.5%计算，剩下的部分方法招标控制价<=5000万的0.5%计算，>5000万的按0.1%计算
            sb.append(" SELECT method_code FROM be_section_method WHERE section_id=:sectionId ");
            RowMapper<BeSectionMethod> rm1 = BeanPropertyRowMapper.newInstance(BeSectionMethod.class);
            BeSectionMethod beSectionMethod = jdbcTemplateService.selectForObject(sb.toString(), paramMap, rm1);
            //查询招标控制价
            sb.setLength(0);
            sb.append(" SELECT param_value FROM be_section_parameter WHERE section_id=:sectionId AND param_id='zbkzj' LIMIT 1 ");
            RowMapper<BeSectionParameter> rm2 = BeanPropertyRowMapper.newInstance(BeSectionParameter.class);
            BeSectionParameter beSectionParameter = jdbcTemplateService.selectForObject(sb.toString(), paramMap, rm2);
            if(beSectionParameter == null ){
                throw new Exception("招标控制价不可以为空！");
            }
            if (!JYPB_CODE.equals(beSectionMethod.getMethodCode()) && OConvertUtils.getDouble(beSectionParameter.getParamValue(), 2) > MONEY) {
                param = 0.001;
            }
            RowMapper<BeSectionInfo> rm3 = BeanPropertyRowMapper.newInstance(BeSectionInfo.class);
            BeSectionInfo beSectionInfo = jdbcTemplateService.selectForObject(" select td_projectId from be_section_info where seq_id=:sectionId ", paramMap, rm3);
            paramMap.put("tdProjectId", beSectionInfo.getTdProjectid());
            sb.setLength(0);
            sb.append(" select v.BidID enterpriseId,sum(errorCount) errorCount  from ( ");
            sb.append(" select bn.enterprise_id as BidID,bn.mano_ManageNodeID as ManageNodeID, ");
            sb.append(" case when ABS(Round(v1.TotalCost, 2)-ifnull(bn.mano_Total,0)>=ifnull(bn.mano_Total,0)* ");
            sb.append(param);
            sb.append(" ) then 1 else 0 end as errorCount ");
            sb.append(" from td_ManageNode_Bid bn ");
            sb.append(" join (select mano_ProjectID,enterprise_id, mano_ManageNodeID,mano_IdxCode,sum(Total) as TotalCost ");
            sb.append(" from (select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode, 1 as CostType, ");
            sb.append(" (select sum(buno_Total) from td_BudgetNode_Bid  ");
            sb.append(" where buno_ManageNodeID=mn.mano_ManageNodeID and buno_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id and buno_Type = 2  ");
            sb.append(" ) as Total ");
            sb.append(" from td_ManageNode_Bid mn ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union  ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,2.1 as CostType, ");
            sb.append(" (select sum(meno_Total) from td_MeasuresNode_Bid  ");
            sb.append(" where meno_ManageNodeID=mn.mano_ManageNodeID and meno_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id and length(meno_IdxCode)=9 and left(meno_Type, 1)='1' ");
            sb.append(" ) as Total  ");
            sb.append(" from td_ManageNode_Bid mn ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union  ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,2 as CostType, ");
            sb.append(" (select sum(meno_Total) from td_MeasuresNode_Bid  ");
            sb.append(" where meno_ManageNodeID=mn.mano_ManageNodeID and meno_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id and length(meno_IdxCode)>6 and meno_Type = '2'  ");
            sb.append("  ) as Total ");
            sb.append(" from td_ManageNode_Bid mn ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union  ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,3 as CostType, ");
            sb.append(" (select sum(otno_Total) from td_OtherNode_Bid ");
            sb.append(" where otno_ManageNodeID=mn.mano_ManageNodeID and otno_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id and length(otno_IdxCode)=6 ");
            sb.append("  ) as Total  ");
            sb.append(" from td_ManageNode_Bid mn  ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append("  union ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,4 as CostType, ");
            sb.append(" (select sum(otco_Total) from td_OtherCost_Bid  ");
            sb.append(" where otco_ManageNodeID=mn.mano_ManageNodeID and otco_CostType = '41' and otco_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id  ");
            sb.append(" ) as Total ");
            sb.append(" from td_ManageNode_Bid mn ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,4 as CostType, ");
            sb.append(" (select sum(otco_Total) from td_OtherCost_Bid  ");
            sb.append(" where otco_ManageNodeID=mn.mano_ManageNodeID and otco_CostType = '42' and otco_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id ");
            sb.append(" ) as Total ");
            sb.append(" from td_ManageNode_Bid mn  ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,5 as CostType, ");
            sb.append(" (select sum(otco_Total) from td_OtherCost_Bid  ");
            sb.append(" where otco_ManageNodeID=mn.mano_ManageNodeID and otco_CostType = '5' and otco_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id  ");
            sb.append(" ) as Total  ");
            sb.append(" from td_ManageNode_Bid mn  ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId  ");
            sb.append(" union ");
            sb.append(" select mano_ProjectID, enterprise_id, mano_ManageNodeID, mano_Name, mano_IdxCode,0 as CostType, ");
            sb.append(" (select sum(mano_Total) from td_ManageNode_Bid  ");
            sb.append(" where mano_ParentID=mn.mano_ManageNodeID and mano_ProjectID = mn.mano_ProjectID and enterprise_id = mn.enterprise_id  ");
            sb.append(" ) as Total  ");
            sb.append(" from td_ManageNode_Bid mn  ");
            sb.append(" where mn.mano_ProjectID=:tdProjectId ");
            sb.append(" ) as v ");
            sb.append(" group by mano_ProjectID,enterprise_id, mano_ManageNodeID,mano_IdxCode  ");
            sb.append(" ) as v1  on bn.mano_ProjectID = v1.mano_ProjectID and bn.enterprise_id = v1.enterprise_id and bn.mano_ManageNodeID = v1.mano_ManageNodeID ");
            sb.append(" where exists(select * from td_ManageNode_Bid where mano_ProjectID = bn.mano_ProjectID and enterprise_id = bn.enterprise_id and mano_ParentID = bn.mano_ManageNodeID)) v ");
            sb.append(" group by BidID ");
            List<Map<String, Object>> enterList = jdbcTemplateService.selectForList(sb.toString(), paramMap);
            //保存计算结果
            saveResult(paramMap, enterList);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception("*****计算商务标评审-计算错误检查失败*****");
        }
    }

    private void saveResult(Map<String, Object> paramMap, List<Map<String, Object>> enterList) throws Exception {
        try {
            List<BeComputerResult> beComputerResultList = new ArrayList<>();
            BeComputerResult beComputerResult = null;
            for (Map<String, Object> map : enterList) {
                beComputerResult = new BeComputerResult();
                beComputerResult.setSeqId(IdsUtil.uuid());
                beComputerResult.setSectionStepId(OConvertUtils.getString(paramMap.get("sectionStepId")));
                beComputerResult.setSectionId(OConvertUtils.getString(paramMap.get("sectionId")));
                beComputerResult.setEnterpriseId(OConvertUtils.getString(map.get("enterpriseId")));
                //错误数
                beComputerResult.setC1(OConvertUtils.getString(map.get("errorCount")));
                //是否通过
                if (OConvertUtils.getInt(map.get("errorCount")) > Constants.ZERO) {
                    beComputerResult.setIsPassed(Constants.ZERO.toString());
                } else {
                    beComputerResult.setIsPassed(Constants.ONE.toString());
                }
                beComputerResult.setCreateTime(DateUtil.now());
                beComputerResultList.add(beComputerResult);
            }
            //批量转数组
            SqlParameterSource[] beanSources = SqlParameterSourceUtils.createBatch(beComputerResultList);
            //删除已存在结果
            jdbcTemplateService.update(" DELETE FROM be_computer_result WHERE section_id=:sectionId AND section_step_id =:sectionStepId ", paramMap);
            //批量插入
            jdbcTemplateService.bathInsert(" INSERT INTO be_computer_result(seq_id,section_step_id,section_id,enterprise_id,c1,is_passed,create_time) " +
                    " VALUES(:seqId, :sectionStepId, :sectionId,:enterpriseId,:c1,:isPassed,:createTime) ", beanSources);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }
}
